﻿using ClockInLearning.Db;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching;
using Microsoft.Extensions.Caching.Memory;
using ClockInLearning.Dto;
using ClockInLearning.Tools;

namespace ClockInLearning
{
    // ActionFilterAttribute特性，在调用action之前先触发该特性
    // 对需要校验token的接口进行token校验，并更新token时间
    // 由于该特性中添加了数据上下文的注入，所以在使用时使用ServiceFilter，并在startup.cs中添加相关服务
    public class ApiFilter : ActionFilterAttribute
    {
        private readonly AppDbContext _context;

        public ApiFilter(AppDbContext context)
        {
            _context = context;
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            try
            {
                //获取请求头中的Token
                var token = context.HttpContext.Request.Headers["token"].ToString();
                //验证token
                if (!string.IsNullOrWhiteSpace(token) && CheckToken(token))
                {
                    base.OnActionExecuting(context);
                }
                else
                {
                    context.Result = new JsonResult(new ServiceResult()
                    {
                        Code = ServiceResult.ServiceResultCode.Failed,
                        Message = "token异常"
                    });
                }
            }
            catch (Exception ex)
            {
                context.Result = new JsonResult(new ServiceResult()
                {
                    Code = ServiceResult.ServiceResultCode.Failed,
                    Message = ex.Message
                });
            }
        }

        private bool CheckToken(string token)
        {
            var lastToken = _context.Tokens.Where(x => x.Token == token).FirstOrDefault();
            if (lastToken == null)
            {
                return false;
            }
            else
            {
                if ((DateTime.Now - lastToken.LastTime).TotalMinutes > 60)
                {
                    throw new Exception("请求token超时");
                }
                else
                {
                    lastToken.LastTime = DateTime.Now;
                    _context.SaveChanges();

                    //记入全局变量
                    CallContext.SetData("token", lastToken);

                    return true;
                }
            }
        }
    }
}
